package com.dlc.felear.xiaoensale.deviceControlSf;

import android.util.Log;

import com.dlc.felear.xiaoensale.constant.Constant;
import com.dlc.felear.xiaoensale.helper.JsonHelper;
import com.dlc.felear.xiaoensale.utils.HexUtil;

import org.simple.eventbus.EventBus;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

public class SensorStatusInfo {
    private static final String TAG = "SensorStatusInfo";
    private static SensorStatusInfo instance;
    private Map<Integer, Integer> sensorLastMaps;
    private Map<Integer, Integer> sensorCurrMaps;
    private Map<Integer, Integer> outputIoMaps;
    private ThreadPoolExecutor scheduledThreadPool;
    private SensorStatusCallback sensorStatusCallback;
    private boolean isWork = false;

    private SensorStatusInfo(SensorStatusCallback sensorStatusCallback, ThreadPoolExecutor scheduledThreadPool) {
        this.sensorStatusCallback = sensorStatusCallback;
        sensorCurrMaps = new HashMap<>();
        sensorLastMaps = new HashMap<>();
        outputIoMaps = new HashMap<>();
        this.scheduledThreadPool = scheduledThreadPool;
    }

    public void setIswork() {
        Log.e(TAG, " isWork=" + isWork);
        isWork = true;
    }

    public static SensorStatusInfo getInstance(SensorStatusCallback sensorStatusCallback,
                                               ThreadPoolExecutor scheduledThreadPool) {
        if (instance == null) {
            synchronized (SensorStatusInfo.class) {
                if (instance == null) {
                    instance = new SensorStatusInfo(sensorStatusCallback, scheduledThreadPool);
                }
            }
        }
        return instance;
    }

    public void recieveSensorData(final byte[] data) {
        Log.e(TAG, "input=" + HexUtil.bytes2HexString(data));
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 3; i < data.length - 2; i++) {
                        if (i <= 5) {
                            inputData((byte) ~data[i], i);
                        } else {
                            outPutData((byte) ~data[i], i);
                        }
                    }
                    listence();
                } catch (Exception e) {
                    Log.e(TAG, e.getMessage());
                }
            }
        });
    }

    /**
     * 获取流量计状态（1 正在计数 0计数完成）
     *
     * @return
     */
    public int[] getLlStatus() {
        int[] temp = new int[10];
        temp[0] = sensorCurrMaps.get(1);
        temp[1] = sensorCurrMaps.get(2);
        temp[2] = sensorCurrMaps.get(3);
        temp[3] = sensorCurrMaps.get(4);
        temp[4] = sensorCurrMaps.get(5);
        temp[5] = sensorCurrMaps.get(6);
        temp[6] = outputIoMaps.get(25);
        temp[7] = outputIoMaps.get(26);
        temp[8] = outputIoMaps.get(27);
        temp[9] = outputIoMaps.get(28);
        return temp;
    }

    private void inputData(byte data, int i) {
//        Log.e(TAG,"index="+i+" "+HexUtil.getBinaryStrFromByte(data));
        for (int j = 0; j < 8; j++) {
            int tt = getBit(data, j);
            int key = 8 * (i - 3) + j + 1;
            if (key > 20) {
                continue;
            }
            sensorCurrMaps.put(key, tt);
        }
    }

    /**
     *
     * @return 0停止 1正在转动
     */
    public int getMotorStatus() {
        Log.e(TAG,"outputIoMaps："+ JsonHelper.toJson(outputIoMaps));
        return outputIoMaps.get(31);
    }

    /**
     *
     * @return 0正转 1反转
     */
    public int getMotorDir() {
        return outputIoMaps.get(32);
    }

    private void outPutData(byte data, int i) {
        try {
            for (int j = 0; j < 8; j++) {
                int tt = getBit(data, j);
                int key = 8 * (i - 5) + j - 7;
                if (key > 32) {
                    continue;
                }
                outputIoMaps.put(key, tt);
            }
        } catch (Exception e) {

        }
    }

    private int getBit(byte b, int index) {
        return (b >> index) & 0x01;
    }

    private void listence() {
        try {
            for (int b : sensorCurrMaps.keySet()) {
                int c_value = getMapValue(sensorCurrMaps, b);
                int l_value = getMapValue(sensorLastMaps, b);
                if (c_value != l_value && c_value == 1) {
                    ioTrigger(b, c_value | l_value);
                }
            }
            sensorLastMaps.clear();
            sensorLastMaps.putAll(sensorCurrMaps);
            EventBus.getDefault().post(outputIoMaps, Constant.ACTION_OUTPUT_IO_INFO_RESULT);
            EventBus.getDefault().post(sensorCurrMaps, Constant.ACTION_INPUT_IO_INFO_RESULT);
//            Log.e(TAG, "电机转动状态:" + getMotorStatus() + " 当前方向:" + getMotorDir());
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }

    private void ioTrigger(int num, int value) {
        Log.e(TAG, "num:" + num + " off:" + value + " isWork=" + isWork);
        if (sensorStatusCallback != null && isWork && value == 1) {
            sensorStatusCallback.sensorStatusResultCallback(num, value);
        }
    }

    public int getIoStatus(int ioNum) {
//        Log.e(TAG,"getIoStatus sensorCurrMaps:"+JsonHelper.toJson(sensorCurrMaps));
        if (sensorCurrMaps!=null&&sensorCurrMaps.containsKey(ioNum)) {
            return sensorCurrMaps.get(ioNum);
        }
        return -1;
    }

    public int getIoStatus(int startIo,int endIo) {
        int temp=-1;
        for (int i = startIo+1; i <= endIo; i++) {
            if (sensorCurrMaps.containsKey(i)&&sensorCurrMaps.get(i)==1) {
                temp=i;
            }
        }
//        Log.e("initCurPosition","initCurPosition:"+JsonHelper.toJson(sensorCurrMaps));
        return temp;
    }
    public int getDoStatus(int ioNum) {
        if (outputIoMaps.containsKey(ioNum)) {
            return outputIoMaps.get(ioNum);
        }
        return 0;
    }

    private int getMapValue(Map<Integer, Integer> map, int key) {
        if (!map.containsKey(key)) {
            return 0;
        }
        return map.get(key);
    }

    public interface SensorStatusCallback {
        void sensorStatusResultCallback(int on, int off);
    }
}
